package com.pzhu.user.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.pzhu.base.common.utils.exceptions.Assert;
import com.pzhu.base.common.utils.exceptions.BusinessException;
import com.pzhu.base.common.utils.result.PageData;
import com.pzhu.user.dao.UserDAO;
import com.pzhu.user.domain.entity.User;
import com.pzhu.user.domain.entity.converter.UserEntityConverter;
import com.pzhu.user.domain.ro.UserCreateRO;
import com.pzhu.user.domain.ro.UserSearchRO;
import com.pzhu.user.domain.ro.UserUpdateRO;
import com.pzhu.user.domain.vo.UserSearchVO;
import com.pzhu.user.domain.vo.converter.UserSearchVOConverter;
import com.pzhu.user.rpc.client.AuthClientService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.Objects;

@Slf4j
@Service
@RequiredArgsConstructor
public class UserService {
    private final UserDAO userDAO;
    private final UserSearchVOConverter userSearchVOConverter;
    private final UserEntityConverter userEntityConverter;
    private final AuthClientService authClientService;

    /**
     * 用户搜素
     */
    @Cacheable(value = "userCache", key = "'info'")
    public PageData<UserSearchVO> search(UserSearchRO userSearchRo) {
        Page<User> userPageData = userDAO.page(userSearchRo);
        return userSearchVOConverter.convert(userPageData);
    }

    /**
     * 创建用户
     *
     * @param userCreateRo 用户创建请求
     * @return {@link Long }
     */
    @Transactional(rollbackFor = Exception.class)
    public Long createUser(UserCreateRO userCreateRo) {
        boolean existByUserName = userDAO.existByUserName(userCreateRo.getUsername());
        if (existByUserName) {
            throw new BusinessException("用户名%s已存在".formatted(userCreateRo.getUsername()));
        }
        User user = userEntityConverter.convert(userCreateRo);
        userDAO.save(user);
        return user.getId();
    }

    /**
     * 更新用户
     *
     * @param userId 用户id
     * @param userUpdateRo 用户更新请求
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUser(Long userId, UserUpdateRO userUpdateRo) {
        boolean existed = userDAO.existByUserId(userId);
        if (!existed) {
            throw new BusinessException("用户不存在");
        }
        User updateUser = userEntityConverter.convert(userId, userUpdateRo);
        return userDAO.updateById(updateUser);
    }

    /**
     * 按id删除用户
     *
     * @param userId 用户id
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUserById(Long userId) {
        User user = userDAO.selectByUserId(userId);
        if (Objects.isNull(user)) {
            throw new BusinessException("用户信息不存在！");
        }
        return userDAO.logicDelete(user);
    }

    /**
     * 按id批量删除用户
     *
     * @param userIds 用户id
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteUserByIds(Collection<Long> userIds) {
        if (CollectionUtils.isEmpty(userIds)) {
            return false;
        }
        return userDAO.logicDeleteByIds(userIds);
    }

    public UserSearchVO searchOne(UserSearchRO userSearchRo) {
        if (Objects.nonNull(userSearchRo.getUserId())) {
            User user = userDAO.getById(userSearchRo.getUserId());
            return userSearchVOConverter.convert(user);
        }
        if (Objects.nonNull(userSearchRo.getUsername())) {
            User user = userDAO.selectOneByUsername(userSearchRo.getUsername());
            return userSearchVOConverter.convert(user);
        }
        return null;
    }

    @Transactional(rollbackFor = Exception.class)
    public void changePassword(Long userId, String sourcePassword) {
        String password = authClientService.generatePasswords(sourcePassword);
        userDAO.updateById(User.builder().id(userId).password(password).build());
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean restPassword(Long userId) {
        User user = userDAO.selectOneById(userId);
        Assert.assertNotNull(user, "用户不存在！");
        User updateEntity = new User();
        updateEntity.setId(userId);
        updateEntity.setPassword(authClientService.generatePasswords("123"));
        return userDAO.updateById(updateEntity);
    }
}
